package gen.tools.todolist;

import gen.tools.Widgets;
import gen.tools.structures.ChkInFiles;
import gen.tools.structures.ChkInObj;
import gen.tools.structures.ChkInRecord;
import gen.tools.structures.CraObj;
import gen.tools.structures.CreateCRA;
import gen.tools.structures.DepInfo;
import gen.tools.structures.I1S1;
import gen.tools.structures.ModNode;
import gen.tools.structures.ModNodeAdv;
import gen.tools.structures.ModUnit;
import gen.tools.structures.Performer;
import gen.tools.structures.Req;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

public class IsComplete extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IsComplete() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response);
	}

	@SuppressWarnings("resource")
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		final Widgets wid = new Widgets();
		request.setCharacterEncoding( wid.UIcodeSet );
		response.setCharacterEncoding( wid.UIcodeSet );
		response.setContentType("application/text");
		
		final int itemType = Integer.parseInt( request.getParameter("itemType") );	//主檔的類型
		final int masterId = Integer.parseInt( request.getParameter("masterId") );	//主檔ID
		String strSQL = "";
		
		Object obj = new Object();
		
		Connection conn = null;
		PreparedStatement ps = null;
		PreparedStatement ps2 = null;
		PreparedStatement ps3 = null;
		ResultSet rs = null;
		ResultSet rs2 = null;
		ResultSet rs3 = null;
		
		String jobName = "";				//部署的 job 名稱
		int jobSN = 0;	//部署的 job 序號
		I1S1 i1s1 = null;	//取得最原始觸發的模組，和其繳交ID
		int chkInMainId = 0;
		String oriModId = "";
		String currentModId = "";
		DepInfo di = null;
		ArrayList<I1S1> drs = null; 
		
		try {
			conn = wid.getConn();
			
			switch (itemType) {
			case 1:	//	模組的新增
				strSQL="SELECT t1.modUnitId,t1.subsysId,t1.mrSVNpath,t1.olSVNpath,t1.modUnitTypeId,t1.comment,t1.creatorId FROM modUnits t1,cradetail t2 WHERE t2.modUnitId=t1.modUnitId AND t2.craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				rs.next();
				ModUnit modUnit = new ModUnit();
				modUnit.setModUnitId( rs.getString("modUnitId") );
				modUnit.setSubsysId(rs.getString("subsysId"));
				modUnit.setMrSvnPath(rs.getString("mrSVNpath"));
				modUnit.setOlSvnPath(rs.getString("olSVNpath"));
				modUnit.setModUnitTypeId(rs.getInt("modUnitTypeId"));
				modUnit.setComment(rs.getString("comment"));
				modUnit.setCreatorId(rs.getString("creatorId"));
				
				//找尋員工
				strSQL="SELECT t2.empName FROM mpcraperformers t1,emps t2 WHERE t1.performerId=t2.empId AND t1.isRole='f' AND t1.craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				ArrayList<Performer> performers = new ArrayList<Performer>();
				
				while ( rs.next() ) {
					Performer performer = new Performer();
					performer.setPerformerName( rs.getString("empName") );
					performer.setRole(false);
					performers.add(performer);
				}
				//找尋角色
				strSQL="SELECT t2.roleDesc FROM mpcraperformers t1,roles t2 WHERE t1.performerId=t2.roleId AND t1.isRole='t' AND t1.craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				
				while ( rs.next() ) {
					Performer performer = new Performer();
					performer.setPerformerName( rs.getString("roleDesc") );
					performer.setRole(true);
					performers.add(performer);
				}
				modUnit.setPerformers(performers);
				
				//找尋需求
				strSQL="SELECT t2.reqId,t2.reqDesc FROM mpcrareq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.craDetId=1 AND t1.craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				ArrayList<Req> reqs = new ArrayList<Req>();
				
				while ( rs.next() ) {
					Req req = new Req();
					req.setReqId( rs.getInt("reqId") );
					req.setReqDesc( rs.getString("reqDesc") );
					reqs.add(req);
				}
				modUnit.setReqs(reqs);
				
				obj = modUnit;
				break;
			case 6:	//定義模組相依性
				strSQL="SELECT t3.subsysId,t1.craDetId,t1.modUnitId,t2.modId FROM cramain t3,(cradetail t1 LEFT JOIN cradependency t2 ON t2.craId=t1.craId AND t1.craId=t2.craId AND t1.craDetId=t2.craDetId ) WHERE t1.craId=? AND t3.craId=t1.craId";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				int preCraDetId=0;
				ArrayList<ModNodeAdv> ArrModNode = new ArrayList<ModNodeAdv>();
				while (rs.next()) {
					if ( rs.getInt("craDetId") != preCraDetId ) {
						preCraDetId = rs.getInt("craDetId"); 
						ModNodeAdv modNode = new ModNodeAdv();
						ArrayList<String> arrDsn = new ArrayList<String>();
						modNode.setSubsysId(rs.getString("subsysId"));
						modNode.setCurrentNode(rs.getString("modUnitId"));
						arrDsn.add(rs.getString("modId")==null?"":rs.getString("modId"));
						modNode.setDownStreamNode( arrDsn );
						
						ArrayList<ModNode> cDownStream = wid.getModBEdependency(rs.getString("modUnitId"),false,false,wid.JENKINSURL+"job/"+rs.getString("modUnitId")+"/config.xml","","");
						arrDsn = new ArrayList<String>();
						for (int i=0; i<cDownStream.size();i++) {
							arrDsn.add(cDownStream.get(i).getDownSreamNode());
						}
						modNode.setcDownStreamNode(arrDsn);
						
						ArrModNode.add(modNode);
					} else {
						ArrModNode.get(ArrModNode.size()-1).getDownStreamNode().add( rs.getString("modId"));
					}
				}
				obj = ArrModNode;
				break;
			case 2:	//審核繳交申請
				final int chkInId = masterId;
				strSQL="SELECT creatorId,subsysId,isUrgent,svnMRurl,svnOLurl,svnMRusr,svnOLusr,svnMRver,svnOLver FROM chkinmain WHERE chkInMainId=? AND chkInStatusId=1";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				ChkInRecord cir = new ChkInRecord();
				rs.next();
				cir.setSubsysId( rs.getString("subsysId") );						//子系統
				cir.setUrgent( "t".equalsIgnoreCase( rs.getString("isUrgent") ) );	//是否為緊急上線
				cir.setSvnMRurl( rs.getString("svnMRurl") );						//SVN AP MR的位址
				cir.setSvnMRusr( rs.getString("svnMRusr") );	  					//SVN AP MR的帳號
				cir.setSvnMRver( rs.getInt("svnMRver") );	                        //SVN AP MR的版次
				cir.setSvnOLurl( rs.getString("svnOLurl") );						//SVN AP OL的位址
				cir.setSvnOLusr( rs.getString("svnOLusr") );	  					//SVN AP OL的帳號
				cir.setSvnOLver( rs.getInt("svnOLver") );	                        //SVN AP OL的版次
				cir.setCreatorId( rs.getString("creatorId") );						//繳交人員
				
				final ArrayList<ChkInObj> modObjs = new ArrayList<ChkInObj>();
				strSQL = "SELECT modId FROM chkinmod WHERE chkInMainId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInId);
				rs = ps.executeQuery();
				//開始處理每個模組
				while ( rs.next() ) {
					final ChkInObj modObj = new ChkInObj();
					final String modId = rs.getString("modId");
					final ArrayList<ChkInFiles> mfo = new ArrayList<ChkInFiles>();
					final ArrayList<I1S1> mcr = new ArrayList<I1S1>();
					modObj.setModId( modId );
					
					//開始處理模組的共同需求
					strSQL = "SELECT reqId FROM mpchkinmodcomreq WHERE chkInMainId=? AND modId=?";
					ps2 = conn.prepareStatement(strSQL);
					ps2.setInt(1, chkInId);
					ps2.setString(2, modId );
					rs2 = ps2.executeQuery();
					
					while( rs2.next() ) {
						I1S1 crq = new I1S1();
						crq.setI1( rs2.getInt("reqId") );
						mcr.add(crq);
					}
					modObj.setCommonReqs(mcr);
					
					//開始處理模組內細項
					strSQL = "SELECT chkInDetailId,isMR,fileName,relativePath,fileVer FROM chkInModDetail WHERE chkInMainId=? AND modId=? ORDER BY chkInDetailId ASC";
					ps2 = conn.prepareStatement(strSQL);
					ps2.setInt(1, chkInId);
					ps2.setString(2, modId );
					rs2 = ps2.executeQuery();
					while( rs2.next() ) {
						final ChkInFiles detailObj = new ChkInFiles();
						final int detailId = rs2.getInt("chkInDetailId");			//繳交記錄模組內細項
						final boolean isMR = "t".equalsIgnoreCase( rs2.getString("isMR") );						//從MR來
						final String fileName = rs2.getString("fileName");			//程式名稱
						final String relativePath = rs2.getString("relativePath");	//相對路徑
						final int fileVer = rs2.getInt("fileVer");					//程式版次
						
						detailObj.setChkInDetailId( detailId );
						detailObj.setFileName( fileName );
						detailObj.setFileVer( fileVer );
						detailObj.setRelativePath( relativePath );
						detailObj.setMR( isMR );
						
						//開始處理細項特有的需求
						strSQL = "SELECT reqId FROM mpchkinmoddetailreq WHERE chkInMainId=? AND modId=? AND chkInDetailId=?";
						ps3 = conn.prepareStatement(strSQL);
						ps3.setInt(1, chkInId );
						ps3.setString(2, modId);
						ps3.setInt(3, detailId);
						rs3 = ps3.executeQuery();
						final ArrayList<I1S1> irqs = new ArrayList<I1S1>();		//細項的佃別需求
						while( rs3.next() ) {
							I1S1 irq = new I1S1();
							irq.setI1( rs3.getInt("reqId") );
							irqs.add(irq);
						}
						detailObj.setIndviReqs(irqs);
						mfo.add(detailObj);
					}
					modObj.setChkInfiles(mfo);
					modObjs.add(modObj);
				}
				//開始產生需求描述的對照 (怕傳輸量太大)
				strSQL = "SELECT DISTINCT t1.reqId, t1.reqDesc FROM reqs t1,mpchkinmodcomreq t2 WHERE t1.reqId=t2.reqId AND t2.chkInMainId=? ORDER BY t1.reqId DESC";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInId);
				rs = ps.executeQuery();
				final ArrayList<I1S1> mrs = new ArrayList<I1S1>();
				while (rs.next()) {
					I1S1 mr = new I1S1();
					mr.setI1( rs.getInt("reqId") );
					mr.setS1( rs.getString("reqDesc") );
					mrs.add(mr);
				}
				strSQL = "SELECT DISTINCT t1.reqId, t1.reqDesc FROM reqs t1,mpchkinmoddetailreq t2 WHERE t1.reqId=t2.reqId AND t2.chkInMainId=? ORDER BY t1.reqId DESC";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInId);
				rs = ps.executeQuery();
				while (rs.next()) {
					boolean isNotexist = true;
					final int reqId = rs.getInt("reqId"); 
					for (int i=0;i<mrs.size();i++) {
						if( mrs.get(i).getI1() == reqId ) { isNotexist=false; }
					}
					if ( isNotexist ) {
						I1S1 mr = new I1S1();
						mr.setI1( reqId );
						mr.setS1( rs.getString("reqDesc") );
						mrs.add(mr);	
					}
				}
				cir.setCios(modObjs);
				cir.setMapReq(mrs);
				obj = cir;
				break;
			case 3:	//等待部署
				jobName = request.getParameter("jobName");					//部署的 job 名稱
				currentModId = jobName.substring(jobName.lastIndexOf("_")+1,jobName.length());
				jobSN = Integer.parseInt( request.getParameter("jobSN") );	//部署的 job 序號
				i1s1 = wid.getTopJob(jobName, jobSN);	//取得最原始觸發的模組，和其繳交ID
				chkInMainId = i1s1.getI1();
				oriModId = i1s1.getS1().substring(i1s1.getS1().lastIndexOf("_")+1,i1s1.getS1().length());
				
				di = new DepInfo();
				
				//取得此次繳交相關資訊
				strSQL = "SELECT t2.subsysId,t2.subsysDesc,t1.isUrgent,t1.isDailyBuild,t1.creatorId,t3.empName,t1.cDT FROM chkinmain t1,subsyses t2,emps t3 WHERE t1.creatorId=t3.empId AND t1.subsysId=t2.subsysId AND t1.chkInMainId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInMainId);
				rs = ps.executeQuery();
				rs.next();
				di.setApplierId( rs.getString("creatorId") );
				di.setApplierName( rs.getString("empName") );
				di.setChkInId(chkInMainId);
				di.setcDT( wid.changeTimeFormat(rs.getTimestamp("cDT") ) );
				di.setSubsysId( rs.getString("subsysId") );
				di.setSubsysDesc( rs.getString("subsysDesc") );
				di.setUrgent( "t".equalsIgnoreCase(rs.getString("isUrgent")) );
				di.setDailyBuild( "t".equalsIgnoreCase(rs.getString("isDailyBuild")) );
				di.setOriModId(oriModId);
				di.setJobSN(jobSN);
				
				//取得欲部署的版次 
				strSQL = "SELECT depFileName,deployFileVer FROM bemain WHERE modId=? AND jobSN= ?";
				ps = conn.prepareStatement(strSQL);
				ps.setString(1, jobName);
				ps.setInt(2, jobSN);
				rs = ps.executeQuery();
				rs.next();
				di.setFileVer( rs.getInt("deployFileVer") );
				di.setFileName( rs.getString("depFileName") );
				di.setModId(currentModId);
				//	取得這次部署相關的需求
				drs = new ArrayList<I1S1>(); 
				//	先取得共通需求
				strSQL = "SELECT t2.reqId,t2.reqDesc FROM mpchkinmodcomreq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.chkInMainId=? ORDER BY t2.reqId DESC";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInMainId);
				rs = ps.executeQuery();
				while( rs.next() ) {
					boolean isNotContained = true;
					final int reqId = rs.getInt("reqId");
					for(int i=0;i<drs.size();i++) {
						if( drs.get(i).getI1()==reqId ) {
							isNotContained = false;
						}
					}
					if( isNotContained ) {
						final I1S1 dr = new I1S1();
						dr.setI1( reqId );
						dr.setS1( rs.getString("reqDesc") );
						drs.add(dr);						
					}
				}
				
				//	取得個別需求
				strSQL = "SELECT DISTINCT t2.reqId, t2.reqDesc FROM mpchkinmoddetailreq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.chkInMainId=? AND t1.modId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setString(1, oriModId);
				ps.setInt(2, chkInMainId);
				rs = ps.executeQuery();
				while( rs.next() ) {
					final I1S1 dr = new I1S1();
					dr.setI1( rs.getInt("reqId") );
					dr.setS1( rs.getString("reqDesc") );
					
					boolean isNotExist=true;	//已存在的便不再加入
					for( int i=0;i<drs.size();i++ ) {
						if( drs.get(i).getI1() == rs.getInt("reqId") ) { isNotExist=false; }
					}
					if ( isNotExist ) { drs.add(dr); }
				}
				
				di.setReqs(drs);
				obj = di;
				break;
			case 4:	//回覆測試結果
				jobName = request.getParameter("jobName");					//部署的 job 名稱
				currentModId = jobName.substring(jobName.lastIndexOf("_")+1,jobName.length());
				jobSN = Integer.parseInt( request.getParameter("jobSN") );	//部署的 job 序號
				System.out.println("動作：回覆測試結果，要處理的Job為："+jobName+",序號為："+jobSN);
				i1s1 = wid.getTopJob(jobName, jobSN);	//取得最原始觸發的模組，和其繳交ID
				chkInMainId = i1s1.getI1();
				oriModId = i1s1.getS1().substring(i1s1.getS1().lastIndexOf("_")+1,i1s1.getS1().length());
				
				di = new DepInfo();
				
				//取得此次繳交相關資訊
				strSQL = "SELECT t2.subsysId,t2.subsysDesc,t1.isUrgent,t1.isDailyBuild,t1.creatorId,t3.empName,t1.cDT FROM chkinmain t1,subsyses t2,emps t3 WHERE t1.creatorId=t3.empId AND t1.subsysId=t2.subsysId AND t1.chkInMainId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInMainId);
				rs = ps.executeQuery();
				rs.next();
				di.setApplierId( rs.getString("creatorId") );
				di.setApplierName( rs.getString("empName") );
				di.setChkInId(chkInMainId);
				di.setcDT( wid.changeTimeFormat(rs.getTimestamp("cDT") ) );
				di.setSubsysId( rs.getString("subsysId") );
				di.setSubsysDesc( rs.getString("subsysDesc") );
				di.setUrgent( "t".equalsIgnoreCase(rs.getString("isUrgent")) );
				di.setDailyBuild( "t".equalsIgnoreCase(rs.getString("isDailyBuild")) );
				di.setOriModId(oriModId);
				di.setJobSN(jobSN);
				
				//取得欲部署的版次 
				strSQL = "SELECT depFileName,deployFileVer FROM bemain WHERE modId=? AND jobSN= ?";
				ps = conn.prepareStatement(strSQL);
				ps.setString(1, jobName);
				ps.setInt(2, jobSN);
				rs = ps.executeQuery();
				rs.next();
				di.setFileVer( rs.getInt("deployFileVer") );
				di.setFileName( rs.getString("depFileName") );
				di.setModId(currentModId);
				//	取得這次部署相關的需求
				drs = new ArrayList<I1S1>(); 
				//	先取得共通需求
				strSQL = "SELECT t2.reqId,t2.reqDesc FROM mpchkinmodcomreq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.chkInMainId=? ORDER BY t2.reqId DESC";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, chkInMainId);
				rs = ps.executeQuery();
				while( rs.next() ) {
					final I1S1 dr = new I1S1();
					dr.setI1( rs.getInt("reqId") );
					dr.setS1( rs.getString("reqDesc") );
					drs.add(dr);
				}
				
				//	取得個別需求
				strSQL = "SELECT DISTINCT t2.reqId, t2.reqDesc FROM mpchkinmoddetailreq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.chkInMainId=? AND t1.modId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setString(1, oriModId);
				ps.setInt(2, chkInMainId);
				rs = ps.executeQuery();
				while( rs.next() ) {
					final I1S1 dr = new I1S1();
					dr.setI1( rs.getInt("reqId") );
					dr.setS1( rs.getString("reqDesc") );
					
					boolean isNotExist=true;	//已存在的便不再加入
					for( int i=0;i<drs.size();i++ ) {
						if( drs.get(i).getI1() == rs.getInt("reqId") ) { isNotExist=false; }
					}
					if ( isNotExist ) { drs.add(dr); }
				}
				
				di.setReqs(drs);
				obj = di;
				break;
			case 5:	//異動申請
				CreateCRA cc = new CreateCRA();
				ArrayList<CraObj> cos = new ArrayList<CraObj>(); 
				
				strSQL = "SELECT t2.empId,t2.empName,t1.subsysId FROM cramain t1,emps t2 WHERE t1.creatorId=t2.empId AND t1.craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				rs.next();
				cc.setCraId(masterId);
				cc.setSubsysId(rs.getString("subsysId"));
				cc.setCreatorId( rs.getString("empId") );
				
				strSQL = "SELECT modUnitId FROM cradetail WHERE craId=?";
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, masterId);
				rs = ps.executeQuery();
				while( rs.next() ) {
					final String modId = rs.getString("modUnitId");
					final CraObj co = new CraObj();
					co.setModId(modId);
					
					//找尋員工
					strSQL="SELECT t2.empName FROM mpcraperformers t1,emps t2 WHERE t1.performerId=t2.empId AND t1.isRole='f' AND t1.craId=?";
					ps2 = conn.prepareStatement(strSQL);
					ps2.setInt(1, masterId);
					rs2 = ps2.executeQuery();
					ArrayList<Performer> pfs = new ArrayList<Performer>();
					
					while ( rs2.next() ) {
						final Performer pf = new Performer();
						pf.setPerformerName( rs2.getString("empName") );
						pf.setRole(false);
						pfs.add(pf);
					}
					//找尋角色
					strSQL="SELECT t2.roleDesc FROM mpcraperformers t1,roles t2 WHERE t1.performerId=t2.roleId AND t1.isRole='t' AND t1.craId=?";
					ps2 = conn.prepareStatement(strSQL);
					ps2.setInt(1, masterId);
					rs2 = ps2.executeQuery();
					
					while ( rs2.next() ) {
						final Performer pf = new Performer();
						pf.setPerformerName( rs2.getString("roleDesc") );
						pf.setRole(true);
						pfs.add(pf);
					}
					co.setPerformers(pfs);
					
					//找尋需求
					strSQL="SELECT t2.reqId,t2.reqDesc FROM mpcrareq t1,reqs t2 WHERE t1.reqId=t2.reqId AND t1.craDetId=1 AND t1.craId=?";
					ps2 = conn.prepareStatement(strSQL);
					ps2.setInt(1, masterId);
					rs2 = ps2.executeQuery();
					ArrayList<Req> rqs = new ArrayList<Req>();
					
					while ( rs2.next() ) {
						final Req req = new Req();
						req.setReqId( rs2.getInt("reqId") );
						req.setReqDesc( rs2.getString("reqDesc") );
						rqs.add(req);
					}
					co.setReqs(rqs);
					cos.add(co);
				}
				cc.setCraObj(cos);
				obj = cc;
				break;
			}	
		} catch (Exception e) {
			wid.errLog(e);
		} finally {
			try {
				if ( rs !=null ) {rs.close();}
				if ( rs2 !=null ) {rs2.close();}
				if ( rs3 !=null ) {rs3.close();}
				if ( ps !=null ) {ps.close();}
				if ( ps2 !=null ) {ps2.close();}
				if ( ps3 !=null ) {ps3.close();}
				if ( conn !=null ) {conn.close();}	
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		response.getWriter().write(new Gson().toJson(obj));
	}

	
}
